package net.za.cair.dip.transform;

import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import net.za.cair.dip.model.OntologyStructure;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.*;
import org.semanticweb.owlapi.reasoner.InconsistentOntologyException;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;

import uk.ac.manchester.cs.owl.owlapi.mansyntaxrenderer.ManchesterOWLSyntaxOWLObjectRendererImpl;

/*
 * Copyright (C) 2011, Centre for Artificial Intelligence Research
 *
 * Modifications to the initial code base are copyright of their
 * respective authors, or their employers as appropriate.  Authorship
 * of the modifications may be determined from the ChangeLog placed at
 * the end of this file.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * Author: Kody Moodley<br>
 * Centre for Artificial Intelligence Research<br>
 * UKZN and CSIR<br>
 * Date: 10-Oct-2011<br><br>
 */

public class AxiomETransformFactory{
	private ArrayList<ArrayList<OWLAxiom>> eTransforms;
	private ArrayList<OWLAxiom> e0;		
	private OWLOntologyManager manager;
	private OWLReasonerFactory reasonerFactory;
	private OntologyStructure ontologyStructure;
	public ArrayList<OWLAxiom> infiniteRank;
	public int entailmentChecks;
	
	public AxiomETransformFactory(OWLReasonerFactory reasonerFactory, OntologyStructure ontologyStructure) throws OWLException{
		ManagementFactory.getThreadMXBean();
		entailmentChecks = 0;
		this.ontologyStructure = ontologyStructure;
		this.reasonerFactory = reasonerFactory;
		new ManchesterOWLSyntaxOWLObjectRendererImpl();
		e0 = this.ontologyStructure.dBox.getAxiomsAsList();
		eTransforms = new ArrayList<ArrayList<OWLAxiom>>();		
		eTransforms.add(e0);
		
		manager = OWLManager.createOWLOntologyManager();
		manager.getOWLDataFactory();
	}
	
	public ArrayList<ArrayList<OWLAxiom>> generateETransforms() throws OWLException{		
		boolean fixedPointReached = false;		
		while (!fixedPointReached){
			ArrayList<OWLAxiom> tmp2 = null;
			tmp2 = genNextETransform(e0);
			if (tmp2.containsAll(e0)){
				fixedPointReached = true;
				infiniteRank = e0;
			}
			else{
				eTransforms.add(tmp2);
				e0 = tmp2;
			}
		}	
		//System.out.println("Entailment Checks: " + entailmentChecks);
		return eTransforms;
	}
	
	private ArrayList<OWLAxiom> genNextETransform(ArrayList<OWLAxiom> axioms) throws OWLException{
		ArrayList<OWLAxiom> result = new ArrayList<OWLAxiom>();
		/************************************************Mat(O) subs not C METHOD***********************************************************/
		/*OWLOntology ontology = manager.createOntology(ontologyStructure.bBox.getAxioms());
		OWLReasoner entailChecker = reasonerFactory.createReasoner(ontology);
	
		DBox dBox = new DBox(axioms);
		OWLClassExpression sBoxMaterialization = dataF.getOWLObjectIntersectionOf(AxiomManipulator.getMaterialization(ontologyStructure.sBox));
		OWLClassExpression dBoxMaterialization = dataF.getOWLObjectIntersectionOf(AxiomManipulator.getMaterialization(dBox));
		OWLClassExpression lhsOfExceptionalityCheck = dataF.getOWLObjectIntersectionOf(sBoxMaterialization, dBoxMaterialization);
		
		for (OWLAxiom axiom: axioms){	
			OWLSubClassOfAxiom subClsAxiom = (OWLSubClassOfAxiom)axiom;
			OWLClassExpression rhsOfExceptionalityCheck = dataF.getOWLObjectComplementOf(subClsAxiom.getSubClass());
			OWLSubClassOfAxiom exceptionalityCheck = dataF.getOWLSubClassOfAxiom(lhsOfExceptionalityCheck, rhsOfExceptionalityCheck);
			
			try{
				entailmentChecks++;
				if (entailChecker.isEntailed(exceptionalityCheck)){
					result.add(axiom);
				}
			}
			catch(InconsistentOntologyException ioe){
				System.out.println("Inconsistent Ontology!");		
			}
		}*/
		/***********************************************************************************************************************************/
		/************************************************C subs bottom METHOD***************************************************************/
		Set<OWLAxiom> allAxioms = new HashSet<OWLAxiom>();
		//allAxioms.addAll(ontologyStructure.bBox.getAxioms());
		allAxioms.addAll(ontologyStructure.sBox.getAxioms());
		allAxioms.addAll(axioms);
		
		OWLOntology ontology = manager.createOntology(allAxioms);
		OWLReasoner entailChecker = reasonerFactory.createReasoner(ontology);
		
		for (OWLAxiom axiom: axioms){	
			OWLSubClassOfAxiom subClsAxiom = (OWLSubClassOfAxiom)axiom;
			
			try{
				entailmentChecks++;
				if (!entailChecker.isSatisfiable(subClsAxiom.getSubClass())){
					result.add(axiom);
				}
			}
			catch(InconsistentOntologyException ioe){
				System.out.println("Inconsistent Ontology!");		
			}
		}
		/***********************************************************************************************************************************/
		//System.out.println("exceptional size: " + result.size());
		return result;
	}
}
